// Package object 用于创建一个线程安全的字符串对象且提供对象的方法简易调用封装
package object

import ( // 导入相关依赖包
	"fmt"     // 导入格式化I/O的包
	"strings" // 导入字符串操作的包
	"sync"    // 导入同步原语的包，例如互斥锁
)

// stringLocker 包含基本的锁操作
type stringLocker interface {
	Lock()    // 加锁方法
	Unlock()  // 解锁方法
	RLock()   // 读锁方法
	RUnlock() // 读解锁方法
}

// stringNotLocker 用于实现stringLocker接口，但方法为空
type stringNotLocker struct{}

func (stringNotLocker) Lock()    {} // 加锁，不执行任何操作
func (stringNotLocker) Unlock()  {} // 解锁，不执行任何操作
func (stringNotLocker) RLock()   {} // 读锁，不执行任何操作
func (stringNotLocker) RUnlock() {} // 读解锁，不执行任何操作

// stringSafeLocker 包含sync.RWMutex用于线程安全的读写锁定
type stringSafeLocker struct {
	locker sync.RWMutex // 声明读写互斥锁
}

func (l *stringSafeLocker) Lock()    { l.locker.Lock() }    // 加锁
func (l *stringSafeLocker) Unlock()  { l.locker.Unlock() }  // 解锁
func (l *stringSafeLocker) RLock()   { l.locker.RLock() }   // 读锁
func (l *stringSafeLocker) RUnlock() { l.locker.RUnlock() } // 读解锁

// String 结构体，用于存储单个字符串及其锁
type String struct {
	Value  string       // 存储字符串的变量
	locker stringLocker // 使用stringLocker接口类型来实现锁定
}

// NewString 函数创建一个String对象，可以选择是否启用线程安全
func NewString(value string, threadSafe bool) *String {
	s := &String{Value: value} // 创建String实例
	if threadSafe {
		s.locker = &stringSafeLocker{} // 如果需要线程安全，则使用StringSafeLocker
	} else {
		s.locker = stringNotLocker{} // 否则使用stringNotLocker，不做任何锁操作
	}
	return s // 返回String实例
}

// Concat 方法将给定的字符串连接到String对象上
func (s *String) Concat(value string) *String {
	s.locker.Lock()         // 加锁
	defer s.locker.Unlock() // 延迟解锁
	s.Value += value        // 字符串连接操作
	return s                // 返回修改后的String对象
}

// Count 方法返回String中某子串出现的次数
func (s *String) Count(substr string) int {
	s.locker.RLock()                      // 读锁
	defer s.locker.RUnlock()              // 延迟读解锁
	return strings.Count(s.Value, substr) // 计算子串出现次数并返回
}

// Contains 方法检查String是否包含给定的字符串
func (s *String) Contains(value string) bool {
	s.locker.RLock()                        // 读锁
	defer s.locker.RUnlock()                // 延迟读解锁
	return strings.Contains(s.Value, value) // 判断是否包含给定字符串并返回结果
}

// Display 方法打印String的值
func (s *String) Display() {
	s.locker.RLock()         // 读锁
	defer s.locker.RUnlock() // 延迟读解锁
	fmt.Println(s.Value)     // 输出String的值
}

// DisplayType 方法打印String的类型
func (s *String) DisplayType() {
	fmt.Printf("%T\n", s) // 输出String对象的类型
}

// Equal 方法比较String的值和给定的字符串是否相等
func (s *String) Equal(value string) bool {
	s.locker.RLock()         // 读锁
	defer s.locker.RUnlock() // 延迟读解锁
	return s.Value == value  // 比较字符串是否相等并返回结果
}

// EqualFold 方法在不区分大小写的情况下比较String的值和给定字符串是否相同
func (s *String) EqualFold(value string) bool {
	s.locker.RLock()                         // 读锁
	defer s.locker.RUnlock()                 // 延迟读解锁
	return strings.EqualFold(s.Value, value) // 不区分大小写比较字符串是否相同并返回结果
}

// Fields 方法按照空白符分割String的值，并返回一个切片
func (s *String) Fields() []string {
	s.locker.RLock()               // 读锁
	defer s.locker.RUnlock()       // 延迟读解锁
	return strings.Fields(s.Value) // 分割字符串并返回字符串切片
}

// Get 方法返回String的值
func (s *String) Get() string {
	s.locker.RLock()         // 读锁
	defer s.locker.RUnlock() // 延迟读解锁
	return s.Value           // 返回String的值
}

// HasPrefix 方法检查String的值是否有指定的前缀
func (s *String) HasPrefix(prefix string) bool {
	s.locker.RLock()                          // 读锁
	defer s.locker.RUnlock()                  // 延迟读解锁
	return strings.HasPrefix(s.Value, prefix) // 检查前缀并返回结果
}

// HasSuffix 方法检查String的值是否有指定的后缀
func (s *String) HasSuffix(suffix string) bool {
	s.locker.RLock()                          // 读锁
	defer s.locker.RUnlock()                  // 延迟读解锁
	return strings.HasSuffix(s.Value, suffix) // 检查后缀并返回结果
}

// Index 方法返回子串在String中首次出现的索引值，如果没有则返回-1
func (s *String) Index(substr string) int {
	s.locker.RLock()                      // 读锁
	defer s.locker.RUnlock()              // 延迟读解锁
	return strings.Index(s.Value, substr) // 返回子串首次出现的索引值
}

// IsEmpty 方法检查String是否为空
func (s *String) IsEmpty() bool {
	s.locker.RLock()         // 读锁
	defer s.locker.RUnlock() // 延迟读解锁
	return len(s.Value) == 0 // 返回String是否为空的结果
}

// LastIndex 方法返回子串在String中最后一次出现的索引值，如果没有则返回-1
func (s *String) LastIndex(substr string) int {
	s.locker.RLock()                          // 读锁
	defer s.locker.RUnlock()                  // 延迟读解锁
	return strings.LastIndex(s.Value, substr) // 返回子串最后一次出现的索引值
}

// Length 方法返回String值的长度
func (s *String) Length() int {
	s.locker.RLock()         // 读锁
	defer s.locker.RUnlock() // 延迟读解锁
	return len(s.Value)      // 返回字符串长度
}

// Repeat 方法返回String值重复n次后的新字符串
func (s *String) Repeat(n int) string {
	s.locker.RLock()                  // 读锁
	defer s.locker.RUnlock()          // 延迟读解锁
	return strings.Repeat(s.Value, n) // 返回重复n次的字符串
}

// Replace 方法在String值中将old子串替换为new子串，最多替换n个；如果n<0，则替换所有old子串
func (s *String) Replace(old, new string, n int) string {
	s.locker.Lock()                              // 加锁
	defer s.locker.Unlock()                      // 延迟解锁
	return strings.Replace(s.Value, old, new, n) // 执行替换操作并返回结果
}

// Set 方法设置String的值，如果新值与旧值相同，则不进行操作
func (s *String) Set(value string) {
	if value == s.Value { // 如果新值和旧值相同则直接返回
		return
	}
	s.locker.Lock()         // 加锁
	defer s.locker.Unlock() // 延迟解锁
	s.Value = value         // 设置新值
}

// Split 方法将String的值按照sep分割，并返回一个字符串切片
func (s *String) Split(sep string) []string {
	s.locker.RLock()                   // 读锁
	defer s.locker.RUnlock()           // 延迟读解锁
	return strings.Split(s.Value, sep) // 分割字符串并返回切片
}

// ToLower 方法返回String值的小写形式
func (s *String) ToLower() string {
	s.locker.RLock()                // 读锁
	defer s.locker.RUnlock()        // 延迟读解锁
	return strings.ToLower(s.Value) // 返回小写字符串
}

// ToUpper 方法返回String值的大写形式
func (s *String) ToUpper() string {
	s.locker.RLock()                // 读锁
	defer s.locker.RUnlock()        // 延迟读解锁
	return strings.ToUpper(s.Value) // 返回大写字符串
}

// Trim 方法返回去掉String两侧指定字符集合的新字符串
func (s *String) Trim(cutset string) string {
	s.locker.RLock()                     // 读锁
	defer s.locker.RUnlock()             // 延迟读解锁
	return strings.Trim(s.Value, cutset) // 返回去掉两侧指定字符集的字符串
}

// TrimSpace 方法返回去掉String两侧空白符的新字符串
func (s *String) TrimSpace() string {
	s.locker.RLock()                  // 读锁
	defer s.locker.RUnlock()          // 延迟读解锁
	return strings.TrimSpace(s.Value) // 返回去掉两侧空白符的字符串
}
